﻿using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.Extensions.Http;
using Polly.Timeout;
using System;
using System.Net;
using System.Net.Http;

namespace Order.MicroService.Api.Config
{
    public class HttpClientConfig
    {
        /// <summary>
        /// 注入HttpClient  命名客户端模式
        /// </summary>
        /// <param name="services"></param>
        public static void Register(IServiceCollection services)
        {
            services.AddHttpClient(BaseConfigInfo.TestClient, config =>  //这里指定的name=client_1，可以方便我们后期服用该实例
            {
                config.BaseAddress = new Uri("http://www.baidu.com");
                config.DefaultRequestHeaders.Add("header_1", "header_1");
            });

            services.AddHttpClient(BaseConfigInfo.AccountClient, c =>
            {
                c.BaseAddress = new Uri("http://10.100.50.61:8015");
            });

            services.AddHttpClient();
        }
        /// <summary>
        /// 注入HttpClient  类型化客户端模式
        /// </summary>
        /// <param name="services"></param>
        public static void RegisterTypeClients(IServiceCollection services)
        {
            var RetryPolicy2 = Policy.HandleResult<HttpResponseMessage>(message =>
            {
                return (message.StatusCode == HttpStatusCode.InternalServerError || message.StatusCode == HttpStatusCode.RequestTimeout);

            }).RetryAsync(10, (res, Index) =>
            {
                Console.WriteLine($"执行错误，异常行为：{res?.Result}");
                Console.WriteLine($"2第{Index}次重试");

            });



            // 超时策略
            var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(3));
            var timeoutPolicy1 = Policy.Timeout(3, (context, timespan, task) => {
                Console.WriteLine("执行超时，抛出TimeoutRejectedException异常");
            });
            // 重试策略
            var retryPolicy = HttpPolicyExtensions
                .HandleTransientHttpError()
                .Or<TimeoutRejectedException>()  // thrown by Polly's TimeoutPolicy if the inner call times out
                .RetryAsync(3, (res, Index)=>
                {
                    Console.WriteLine($"第{Index}次重试");
                    Console.WriteLine($"执行错误，异常行为：{res?.Result}");
                });

            var noOp = Policy.NoOpAsync().AsAsyncPolicy<HttpResponseMessage>();


            //类型模式注册HttpClient
            services.AddHttpClient<HttpClientService>(client =>
            {
                client.BaseAddress = new Uri("http://192.168.8.101:8005");
                //client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
                //client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactoryTesting");
            })
            // 重试
            .AddPolicyHandler(request => request.Method == HttpMethod.Get ? retryPolicy : noOp)
            // 超时
            .AddPolicyHandler(timeoutPolicy);
        }
    }
}
